www.gusucode.com > VC++ VTCamera摄像头录像软件源码程序 > VC++ VTCamera摄像头录像软件源码程序/code/FilterTitleOverlay/CScrollController.cpp

    //
// CScrollController.cpp
//

#include <streams.h>
#include "COverlayController.h"
#include "CScrollController.h"

////////////////////////////////////////////////////////////////////////////////////
CScrollController::CScrollController() :
cDefaultStride(10)
{
	mIsBottomScrolling = TRUE;
	mScrollStride      = cDefaultStride;
	SetRectEmpty(&mValidTitleRect);
}

CScrollController::~CScrollController()
{
}

void CScrollController::SetScrollBottomOrTop(BOOL inIsBottom)
{
	mIsBottomScrolling = inIsBottom;
}

BOOL CScrollController::StartTitleOverlay(void)
{
	BOOL pass = COverlayController::StartTitleOverlay();
	if (pass)
	{
		// After title DIB created successfully, we can calculate the
		// start point of Y-axis according to mIsBottomScrolling
		mStartPos.x = mImageWidth - 1;
		if (mIsBottomScrolling)
		{
			mStartPos.y = mImageHeight - mTitleSize.cy;
		}
		else
		{
			mStartPos.y = 0;
		}	

		CalculateScrollStride();       //计算Scroll步长
	}
	return pass;
}

void CScrollController::SideEffectProgressChanged(void)
{
	COverlayController::SideEffectProgressChanged();
	CalculateScrollStride();
}

// Calculate the stride according to the title duration
void CScrollController::CalculateScrollStride(void)
{
	if (mOverlayEndTime != -1)
	{
		double scrollingLength = mImageWidth + mTitleSize.cx;
		mScrollStride = scrollingLength / (mOverlayEndTime - mOverlayStartTime);
	}
	else
	{
		mScrollStride = cDefaultStride;
	}
}

BOOL CScrollController::BeforeActualOverlay(void)
{
	BOOL pass = COverlayController::BeforeActualOverlay();
	if (pass)
	{
		// Calculate for the next progress
		long actualProgress = mOverlayCounter - mOverlayStartTime;
		mStartPos.x = long(mImageWidth - 1 - mScrollStride * actualProgress);
		if (mStartPos.x < 0)
		{
			// Moving out of the left side
			mValidTitleRect.left = -mStartPos.x;
			if (mValidTitleRect.left >= mTitleSize.cx)
			{
				mValidTitleRect.left = mTitleSize.cx - 1;
			}
			mStartPos.x = 0;
			if (mTitleSize.cx - mValidTitleRect.left <= mImageWidth)
			{
				mValidTitleRect.right = mTitleSize.cx - 1;
			}
			else
			{
				mValidTitleRect.right = mValidTitleRect.left + mImageWidth;
			}
		}
		else
		{
			// Moving in the image-width range
			mValidTitleRect.left = 0;
			long currentLength = mImageWidth - mStartPos.x;
			if (currentLength >= mTitleSize.cx)
			{
				mValidTitleRect.right = mTitleSize.cx - 1;
			}
			else
			{
				mValidTitleRect.right = currentLength;
			}
		}
		pass = (mValidTitleRect.right > mValidTitleRect.left);
	}
	return pass;
}

BOOL CScrollController::ActualOverlay(PBYTE inImage)
{
	if (mImageHeight > mTitleSize.cy && mTitleSize.cx > 0 && mTitleSize.cy > 0) 
	{
		// Image may be bottom-up, may be top-down.
		// Anyway retrieve the pointer which point to the top line
		PBYTE   pTopLine      = NULL;
		long    strideInBytes = 0;
		if (mIsBottomUpImage)
		{
			strideInBytes = -mImageWidthInBytes;
		    pTopLine      = inImage + mImageWidthInBytes * (mImageHeight - 1);	
		}
		else
		{
			strideInBytes = mImageWidthInBytes;
			pTopLine      = inImage;
		}
		
		PBYTE  pStartPos = pTopLine + mStartPos.y * strideInBytes + mStartPos.x * mImageBitCount / 8;
		for (DWORD dwY = 0; dwY < (DWORD)mTitleSize.cy; dwY++) 
		{
			PBYTE pbTitle = mTitleDIBBits + mDIBWidthInBytes * ((DWORD)mTitleSize.cy - dwY - 1);
			// Point to the valid start position of title DIB
			pbTitle += (mValidTitleRect.left >> 3);
			long  startLeft = mValidTitleRect.left % 8;
			long  endRight  = startLeft + mValidTitleRect.right - mValidTitleRect.left;
			for (long dwX = startLeft; dwX < endRight; dwX++) 
			{
				if ( !((0x80 >> (dwX & 7)) & pbTitle[dwX >> 3]) ) 
				{
					PBYTE pbPixel = mPixelConverter->NextNPixel(pStartPos, dwX - startLeft);
					if (mIsOverlayByCover)
					{
						mPixelConverter->ConvertByCover(pbPixel);
					}
					else
					{
						mPixelConverter->ConvertByReverse(pbPixel);
					}
				}
			}
			pStartPos += strideInBytes;
		}
	}
	return TRUE;
}